#include <iostream>
#include <pthread.h>
#include <vector>
#include <unistd.h>

using namespace std;

#define NUM 4

int cnt = 0;

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

void *Count(void *args)
{
    pthread_detach(pthread_self()); // 线程分离
    uint64_t num = (uint64_t)args;
    cout << "Thread " << num << " is creat success" << endl;
    usleep(100000);
    while (true)
    {
        pthread_mutex_lock(&lock);
        pthread_cond_wait(&cond, &lock); //
        cout << "Thread " << num << " is running... cnt: " << cnt << endl;
        cnt++;
        usleep(10000);
        pthread_mutex_unlock(&lock);
    }
}

int main()
{
    for (uint64_t i = 1; i <= NUM; i++)
    {
        pthread_t tid;
        pthread_create(&tid, nullptr, Count, (void *)i);
        usleep(1000);
    }

    while (true)
    {
        sleep(1);
        pthread_cond_signal(&cond); // 唤醒一个线程
        cout << "signal one thread..." << endl;
    }
    return 0;
}

// #include <iostream>
// #include <pthread.h>
// #include <vector>
// #include <cstdio>
// #include <unistd.h>

// using namespace std;

// #define NUM 4

// int tickets = 500; // 定义1000张票

// class ThreaInfo
// {
// public:
//     ThreaInfo(const string &threadname, pthread_mutex_t *lock)
//     :threadname_(threadname)
//     ,lock_(lock)
//     {}

// public:
//     string threadname_;
//     pthread_mutex_t *lock_;
// };

// void *GrabTickets(void *args)
// {
//     ThreaInfo *ti = static_cast<ThreaInfo*>(args);
//     string name(ti->threadname_);
//     while(true)
//     {
//         pthread_mutex_lock(ti->lock_); // 加锁
//         if(tickets > 0)
//         {
//             usleep(10000);
//             printf("%s get a ticket: %d\n", name.c_str(), tickets);
//             tickets--;
//             pthread_mutex_unlock(ti->lock_); // 解锁
//         }
//         else
//         {
//             pthread_mutex_unlock(ti->lock_); // 解锁
//             break;
//         }
//         //usleep(13); // 用休眠来模拟抢到票的后续动作
//         // pthread_mutex_unlock(ti->lock_); // 不能在这里解锁，因为 tickets == 0 的时候就直接跳出循环了，导致锁没有被释放，其它线程就会阻塞住
//     }

//     printf("%s quit...\n", name.c_str());
// }

// int main()
// {
//     pthread_mutex_t lock; // 定义一个互斥量
//     pthread_mutex_init(&lock, nullptr); // 初始化互斥量
//     vector<pthread_t> tids;
//     vector<ThreaInfo*> tis;
//     for(int i = 1; i <= NUM; i++)
//     {
//         pthread_t tid;
//         ThreaInfo *ti = new ThreaInfo("Thread-"+to_string(i), &lock);
//         pthread_create(&tid, nullptr, GrabTickets, ti);
//         tids.push_back(tid);
//         tis.push_back(ti);
//     }

//     // 等待所有线程
//     for(auto tid : tids)
//     {
//         pthread_join(tid, nullptr);
//     }

//     // 释放资源
//     for(auto ti : tis)
//     {
//         delete ti;
//     }

//     pthread_mutex_destroy(&lock); // 销毁一个互斥量
//     return 0;
// }
